#include "anry-stock-library-config.h"

static DEBUG_LEVEL g_debug_level = DEBUG_LEVEL_DEBUG;
DEBUG_LEVEL ANRY_STOCK_LIBRARY::GetDebugLevel() {
	return g_debug_level;
}

void ANRY_STOCK_LIBRARY::SetDebugLevel (DEBUG_LEVEL debug_level) {
	g_debug_level = debug_level;
}

static FILE* debug_output_file = NULL;
void ANRY_STOCK_LIBRARY::DebugOutput( enum DEBUG_LEVEL level, const char* fmt, ... )
{
	char buf[1024];
	va_list ap;

	// check if need to print
	if( level < g_debug_level ) return;

	// prepare string to output
	va_start( ap, fmt );
#ifdef _WIN32
	vsnprintf_s( buf, sizeof(buf), sizeof(buf)-1, fmt, ap );
#else
	vsnprintf( buf, sizeof(buf), fmt, ap );
#endif

	// do output
	if( debug_output_file )
	{
		fprintf( debug_output_file, "%s\n", buf );
		fflush( debug_output_file );
	}
	else printf( "%s\n", buf );

	va_end( ap );
}

void ANRY_STOCK_LIBRARY::DebugOutputWithPrefix( enum DEBUG_LEVEL level, const char* prefix, const char* fmt, ... )
{
	char buf[1024];
	va_list ap;

	// check if need to print
	if( level < g_debug_level ) return;

	// prepare string to output
	va_start( ap, fmt );
#ifdef _WIN32
	vsnprintf_s( buf, sizeof(buf), sizeof(buf)-1, fmt, ap );
#else
	vsnprintf( buf, sizeof(buf), fmt, ap );
#endif

	// do output
	if( debug_output_file )
	{
		fprintf( debug_output_file, "%s: %s\n", prefix, buf );
		fflush( debug_output_file );
	}
	else printf( "%s: %s\n", prefix, buf );

	va_end( ap );
}


void ANRY_STOCK_LIBRARY::SetDebugOutputFile( const char* filename )
{
	if( debug_output_file != NULL ) fclose( debug_output_file );
	debug_output_file = fopen( filename, "w" );
}

#if HAVE_BACKTRACE
#include <execinfo.h>
int ANRY_STOCK_LIBRARY::GetCallStack( std::string* p_out_str )
{
	// check input
	if( p_out_str == NULL ) return -1;

	// reset output var
	*p_out_str = SAT_SDK_LIB_Debug::GetVersion() + "\n";

	// address buffer
	void* buffer[128];

	// get trace address
	int nptrs = backtrace( buffer, 128 );

	// output string array
	char** out_str_array = backtrace_symbols( buffer, nptrs );
	if( out_str_array == NULL )
	{
		*p_out_str = "";
		return -1;
	}

	// 
	int j = 0;
	for( j=0; j<nptrs; j++ ) 
	{
		*p_out_str += out_str_array[j];
		*p_out_str += "\n";
	}

	free( out_str_array );

	return 0;
}
#else /* HAVE_BACKTRACE */
int ANRY_STOCK_LIBRARY::GetCallStack( std::string* p_out_str )
{
	return -1;
}
#endif /* HAVE_BACKTRACE */
